package cn.iocoder.yudao.module.erp.controller.admin.stock.goods;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.stock.goods.vo.*;
import cn.iocoder.yudao.module.erp.controller.admin.stock.goodswarehouselink.vo.GoodsWarehouseLinkRespVO;
import cn.iocoder.yudao.module.erp.convert.goods.ErpGoodsConvert;
import cn.iocoder.yudao.module.erp.dal.dataobject.business.warehouse.WarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.goods.GoodsDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.goodswarehouselink.GoodsWarehouseLinkDO;
import cn.iocoder.yudao.module.erp.service.business.warehouse.WarehouseService;
import cn.iocoder.yudao.module.erp.service.stock.goods.GoodsService;
import cn.iocoder.yudao.module.erp.service.stock.goodswarehouselink.GoodsWarehouseLinkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "管理后台 - ERP 物品库")
@RestController
@RequestMapping("/erp/goods")
@Validated
@Slf4j
public class GoodsController {

    @Resource
    private GoodsService goodsService;
    @Resource
    private GoodsWarehouseLinkService goodsWarehouseLinkService;

    @Resource
    private WarehouseService warehouseService;


    @PostMapping("/create")
    @Operation(summary = "创建物品")
    @PreAuthorize("@ss.hasPermission('erp:goods:create')")
    public CommonResult<Long> createGoods(@Valid @RequestBody GoodsSaveReqVO createReqVO) {
        return success(goodsService.createGoods(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新物品")
    @PreAuthorize("@ss.hasPermission('erp:goods:update')")
    public CommonResult<Boolean> updateGoods(@Valid @RequestBody GoodsSaveReqVO updateReqVO) {
        goodsService.updateGoods(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除物品")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:goods:delete')")
    public CommonResult<Boolean> deleteGoods(@RequestParam("id") Long id) {
        goodsService.deleteGoods(id);
        return success(true);
    }

    @DeleteMapping("/delete-any")
    @Operation(summary = "批量删除物品")
    @Parameter(name = "ids", description = "编号列表", required = true)
    @PreAuthorize("@ss.hasPermission('erp:goods:delete')")
    public CommonResult<Boolean> deleteAnyGoods(@RequestParam("ids") List<Long> ids) {
        goodsService.deleteAnyGoods(ids);
        return success(true);
    }

    /**
     * @param id:
      * @return CommonResult<GoodsRespVO>
     * @author Max-u-19
     * @description 优化前的代码，仅作参考，相比优化版其实写起来更快。
     * @date 2024/1/14 14:36
     */
    @GetMapping("/get2")
    @Operation(summary = "获得物品")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:goods:query')")
    public CommonResult<GoodsRespVO> getGoodsOragin(@RequestParam("id") Long id) {
        GoodsDO goods = goodsService.getGoods(id);
        List<GoodsWarehouseLinkDO> goodsWarehouseLinkDOS = goodsWarehouseLinkService.getlinksByGoodsId(id);
        ArrayList<GoodsWarehouseLinkRespVO> warehouseLinkList = new ArrayList<>();
        goodsWarehouseLinkDOS.forEach(goodsWarehouseLinkDO ->{
            WarehouseDO warehouse = warehouseService.getWarehouse(goodsWarehouseLinkDO.getWarehouseId());
            warehouseLinkList.add(new GoodsWarehouseLinkRespVO().setWarehouseName(warehouse.getName()).setInventory(goodsWarehouseLinkDO.getInventory()));
        });
        GoodsRespVO goodsRespVO = BeanUtils.toBean(goods, GoodsRespVO.class);
        goodsRespVO.setWarehouseList(warehouseLinkList);
        return success(goodsRespVO);
    }

    @GetMapping("/get")
    @Operation(summary = "获得物品")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:goods:query')")
    public CommonResult<GoodsRespVO> getGoods(@RequestParam("id") Long id) {
        GoodsDO goods = goodsService.getGoods(id);
        List<GoodsWarehouseLinkRespVO> withWarehouseNames = goodsWarehouseLinkService.getLinkWithWarehouseNamesByGoodsId(id);
        BigDecimal inventorySum = withWarehouseNames.stream().map(GoodsWarehouseLinkRespVO::getInventory).reduce(BigDecimal.ZERO, BigDecimal::add);
        return success(ErpGoodsConvert.INSTANCE.convert(goods, withWarehouseNames,inventorySum));
    }

    @GetMapping("/page")
    @Operation(summary = "获得物品分页")
    @PreAuthorize("@ss.hasPermission('erp:goods:query')")
    public CommonResult<PageResult<GoodsRespVO>> getGoodsPage(@Valid GoodsPageReqVO pageReqVO) {
        PageResult<GoodsDO> pageResult = goodsService.getGoodsPage(pageReqVO);
        List<GoodsDO> list = pageResult.getList();
        if (CollUtil.isEmpty(list)) {
            return success(PageResult.empty());
        }
        List<GoodsRespVO> respVOS = BeanUtils.toBean(list, GoodsRespVO.class);
        respVOS.forEach(goods ->{
            List<GoodsWarehouseLinkDO> goodsWarehouseLinkDOS = goodsWarehouseLinkService.getlinksByGoodsId(goods.getId());
            ArrayList<GoodsWarehouseLinkRespVO> warehouseLinkList = new ArrayList<>();
            BigDecimal count = BigDecimal.valueOf(0);
            for (GoodsWarehouseLinkDO goodsWarehouseLinkDO : goodsWarehouseLinkDOS){
                WarehouseDO warehouse = warehouseService.getWarehouse(goodsWarehouseLinkDO.getWarehouseId());
                warehouseLinkList.add(new GoodsWarehouseLinkRespVO().setWarehouseName(warehouse.getName()).setInventory(goodsWarehouseLinkDO.getInventory()));
                count = count.add(goodsWarehouseLinkDO.getInventory());
            }
            goods.setInventory(count);
            goods.setWarehouseList(warehouseLinkList);
        });
        return success(new PageResult<GoodsRespVO>().setList(respVOS).setTotal((long) respVOS.size()));
    }

    @GetMapping("/bomPage")
    @Operation(summary = "Bom模块获得物品分页")
    @PreAuthorize("@ss.hasPermission('erp:goods:query')")
    public CommonResult<PageResult<GoodsFromBomRespVO>> getGoodsFromBomPage(@Valid GoodsPageReqVO pageReqVO) {
        PageResult<GoodsDO> pageResult = goodsService.getGoodsPage(pageReqVO);
        List<GoodsDO> list = pageResult.getList();
        if (CollUtil.isEmpty(list)) {
            return success(PageResult.empty());
        }
        List<GoodsFromBomRespVO> respVOS = BeanUtils.toBean(list, GoodsFromBomRespVO.class);
        respVOS.forEach(goods ->{
            List<GoodsWarehouseLinkDO> goodsWarehouseLinkDOS = goodsWarehouseLinkService.getlinksByGoodsId(goods.getId());
            ArrayList<GoodsWarehouseLinkRespVO> warehouseLinkList = new ArrayList<>();
//            goodsWarehouseLinkDOS.forEach(goodsWarehouseLinkDO ->{
//                WarehouseDO warehouse = warehouseService.getWarehouse(goodsWarehouseLinkDO.getWarehouseId());
//                warehouseLinkList.add(new GoodsWarehouseLinkRespVO().setWarehouseName(warehouse.getName()).setInventory(goodsWarehouseLinkDO.getInventory()));
//            });
            BigDecimal count = new BigDecimal(0);
            for (GoodsWarehouseLinkDO goodsWarehouseLinkDO : goodsWarehouseLinkDOS){
                WarehouseDO warehouse = warehouseService.getWarehouse(goodsWarehouseLinkDO.getWarehouseId());
                warehouseLinkList.add(new GoodsWarehouseLinkRespVO().setWarehouseName(warehouse.getName()).setInventory(goodsWarehouseLinkDO.getInventory()));
                count =count.add(goodsWarehouseLinkDO.getInventory());
            }
            goods.setInventory(count);
            goods.setWarehouseList(warehouseLinkList);
        });
        return success(new PageResult<GoodsFromBomRespVO>().setList(respVOS).setTotal((long) respVOS.size()));
    }
    @GetMapping("/get-import-template")
    @Operation(summary = "获取导入物品模板")
    public void importTemplate(HttpServletResponse response) throws  IOException {
        //手动创建导入
        List<GoodsImportExcelVO> list = Arrays.asList(
                GoodsImportExcelVO.builder().name("南孚电池").code("WP00002").nameEn("Battery").unit("节")
                        .models("").categoryName("办公用品").maxQuantity(new BigDecimal(100)).minQuantity(new BigDecimal(10)).
                        orderPrice(new BigDecimal(80)).salePrice(new BigDecimal("100.20")).brand("南孚电池").produceModel("313212321")
                        .alarmDay(60).description("这电池不捞").categoryOne("行政物资").categoryTwo("能源").categoryThree("电池")
                        .warehouse("本地仓库").build()
        );
        //输出
        ExcelUtils.write(response, "客户导入模板.xls", "客户列表", GoodsImportExcelVO.class, list);
    }

    /**
     * 导入物品Excel
     * @param file
     * @param updateSupport
     * @return
     * @throws Exception
     */
    @PostMapping("/import")
    @Operation(summary = "导入Excel 物品库")
    @PreAuthorize("@ss.hasPermission('erp:goods:import')")
    @Parameters({
            @Parameter(name="file",description = "Excel文件", required = true),
            @Parameter(name="updateSupport", description = "是否支持更新已存在的数据，默认为false", example = "true")
    })
    public CommonResult<GoodsImportRespVO> importExcel(@RequestParam(value = "file") MultipartFile file,
                                                       @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<GoodsImportExcelVO> list = ExcelUtils.read(file, GoodsImportExcelVO.class);
        return success(goodsService.importGoodsList(list, updateSupport,getLoginUserId()));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出物品 Excel")
    @PreAuthorize("@ss.hasPermission('erp:goods:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportGoodsExcel(@Valid GoodsPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<GoodsDO> list = goodsService.getGoodsPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "物品.xls", "数据", GoodsRespVO.class,
                        BeanUtils.toBean(list, GoodsRespVO.class));
    }

}